package com.atguigu.exam.service.impl;


import com.atguigu.exam.entity.Category;
import com.atguigu.exam.entity.Question;
import com.atguigu.exam.mapper.CategoryMapper;
import com.atguigu.exam.mapper.QuestionMapper;
import com.atguigu.exam.service.CategoryService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.poifs.property.Parent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Autowired
    private QuestionMapper questionMapper;


    @Override
    public List<Category> getCategoryList() {
        //步骤一 查询所有分类
        List<Category> categoryList = list();
        //步骤二 完成分类分析的题目数量填充
        fillQuestionCount(categoryList);
        //步骤三 返回完整结构
        return categoryList;
    }

    @Override
    public List<Category> getCategoryTreeList() {
        // 步骤一 查询所有分类信息
        List<Category> categoryList = list();
        //步骤二 完成分类分析的题目数量填充
        fillQuestionCount(categoryList);
        //步骤三 给所有分类根据parent_id进行排序
        Map<Long, List<Category>> parentIdMap = categoryList.stream().collect(Collectors.groupingBy(Category::getParentId));
        //步骤四 筛选原来分类集合中，parent_id为0的分类
        List<Category> categoryListResult = categoryList.stream().filter(category -> category.getParentId() == 0).collect(Collectors.toList());
        //步骤五  对筛选后的集合进行循环
        categoryListResult.forEach(category -> {
            //赋值子分类
            List<Category> childCategoryList = parentIdMap.getOrDefault(category.getId(), new ArrayList<>());
            childCategoryList.sort(Comparator.comparing(Category::getSort));
            category.setChildren(childCategoryList);
            //赋值count = 当前count + 子分类的count
            long childCount = childCategoryList.stream().mapToLong(Category::getCount).sum();
            category.setCount(category.getCount() + childCount);
        });
        //6. 返回分类集合 筛选 + 循环赋值
        return categoryListResult;
    }

    @Override
    public void saveCategory(Category category) {
        //1 判断同一父类下不允许重名
        LambdaQueryWrapper<Category> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Category::getParentId, category.getParentId());
        lambdaQueryWrapper.eq(Category::getName, category.getName());
        Long count = count(lambdaQueryWrapper); //count 查询存在的数量
        if (count > 0) {
            Category parent = getById(category.getParentId());
            //不能添加， 同一个父类下名称重复;
            throw new RuntimeException("在%s父分类下，已经存在名为：%s的子分类，本次添加失败！".formatted(parent.getName(), category.getName()));
        }
        //保存
        save(category);
    }

    @Override
    public void updateCategory(Category category) {
        //1.先校验  同一父分类下！ 可以跟自己的name重复，不能跟其他的子分类name重复！
        LambdaQueryWrapper<Category> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Category::getParentId, category.getParentId()); // 同一父分类下！
        lambdaQueryWrapper.ne(Category::getId, category.getId());
        lambdaQueryWrapper.eq(Category::getName, category.getName());
        CategoryMapper categoryMapper = getBaseMapper();
        boolean exists = categoryMapper.exists(lambdaQueryWrapper);
        if (exists) {
            Category parent = getById(category.getParentId());
            //不能添加，同一个父类下名称重复了
            throw new RuntimeException("在%s父分类下，已经存在名为：%s的子分类，本次更新失败！".formatted(parent.getName(),category.getName()));
        }
        //2.再更新
        updateById(category);
    }



    @Override
    public void removeCategoryById(Long id) {
        //1 检查是否一级标题
        Category category = getById(id);
        if (category.getParentId() == 0) {
            throw new RuntimeException("不允许删除固定的一级分类");
        }
        //2. 检查该分类下是否有子分类
        LambdaQueryWrapper<Question> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Question::getCategoryId, id);
        long count = questionMapper.selectCount(lambdaQueryWrapper);
        if (count > 0) {
            throw new RuntimeException("当前:%s分类，关联了%s道题目，无法删除!".formatted(category.getName(), count));

        //3. 以上不都满足， 删除即可[关联子数据，一并删除]
        }
        removeById(id);
    }

    private void fillQuestionCount(List<Category> categoryList) {
        //1. 判断分类集合是否为empty
        if (categoryList == null || categoryList.isEmpty()) {
            throw new RuntimeException("分类集合为空");
        }
        //2.查询所有分类对应的题目数量
        List<Map<Long, Long>> mapList = questionMapper.selectCategoryCount();
        Map<Long, Long> resultCount = mapList.stream().collect(Collectors.toMap(m -> m.get("category_id"), m -> m.get("ct")));
        //3. 进行分类结果填充
        categoryList.forEach(category -> {
            category.setCount(resultCount.getOrDefault(category.getId(),0L));
        });
    }
}
